import os
import openai
from typing import Union
import requests
import json
from http import HTTPStatus
from urllib.parse import urlparse, unquote
from pathlib import PurePosixPath
from dashscope import ImageSynthesis
import dashscope
from utils import create_directory, save_file,load_config


# 加载配置文件代码在 utils.load_config
project_config = load_config("config.json")

client = openai.OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

def create_illustration_prompt(script):
    """
    根据给定的脚本生成插图提示，并通过 API 获取详细插图信息。

    :param script: str，微课程的主题或内容脚本，用于生成插图提示。

    :return: str，生成的插图提示，包含详细的插图信息和格式的 JSON 字符串。
    """

    # 系统消息，指定模型的角色和任务
    system_message = (
        "您是一位插图提示生成专家，专注于为微课程生成详细的插图提示。"
    )

    # 构建插图生成提示
    prompt = f"""生成关于 {script} 的插图。返回仅包含多个插图详细信息的 JSON 数组。
    ### 改进指南:
    - **主题:** 中心概念。
    - **描述:** 详细叙述重点元素、情感和氛围。
    - **场景:** 特定环境（如自然、城市、太空），包括颜色、光线和情绪。
    - **对象:** 主要主题和特征（如人、动物、物体）。
    - **动作:** 对象的动态（如飞行、跳跃、闲逛）。
    - **风格:** 艺术技巧（如抽象、超现实主义、水彩、矢量）。
    - **细节:** 其他特定信息（如纹理、背景元素）。
    ### 生成的提示结构:
    “描述, 场景, 包含对象, 动作. 以风格呈现, 强调细节。”
    ### 提示示例
    [
        {{
            "插图编号": 1,
            "插图位置": "第一课",
            "图片标题": "阳光明媚的日子",
            "插图描述": "一幅富有创意的数字艺术作品，描绘了一只由埃菲尔铁塔构建的长颈鹿。"
        }},
        {{
            "插图编号": 2,
            "插图位置": "第二课",
            "图片标题": "繁星之夜",
            "插图描述": "一幅黑暗幻想肖像，呈现了一匹马奔跑在风暴中，背景火焰般的景观。"
        }}
    ]
    输出格式为JSON。不包含任何额外的文字、解释或评论。"""

    # 调用 API 获取插图数据
    completion = client.chat.completions.create(
        model="qwen-max",
        messages=[
            {"role": "system", "content": system_message},
            {"role": "user", "content": prompt},
        ],
        stream=True
    )

    # 解析 API 返回结果
    generated_content = ""
    for chunk in completion:
        chunk_content = chunk.choices[0].delta.content
        generated_content += chunk_content
        print(chunk_content, end="")

    print("生成的插画提示词:", generated_content)  # 打印生成的提示

    # 返回生成的插图提示
    return generated_content

def create_course_script(topic_name, level_of_explanation, age, creativity_level, humour_level):
    """
    根据主题、解释水平、年龄以及创意和幽默水平生成对应的课程脚本。

    :param topic_name: str，课程主题的名称。
    :param level_of_explanation: str，决定解释的复杂程度，值可以为 '初学者', '中级', '高级'。
    :param age: int，授课对象的年龄。
    :param creativity_level: int，创意的级别（1-10），决定讲解中使用创造性元素的程度。
    :param humour_level: int，幽默的级别（1-10），决定讲解中包含幽默的程度。

    :return: str，生成的课程脚本内容，格式化为Markdown。
    """

    # 确保年龄为字符串类型，以便用作提示中的描述
    age_str = str(age)

    # 定义各级别的解释方式
    explanation_levels = {
        '初学者': "用简单易懂的方式解释，帮助读者理解直觉、逻辑和重要性。",
        '中级': "以更复杂和深入的方式解释，假设读者有一些先前知识和理解。",
        '高级': "深入讲解主题细节，假设读者有扎实基础，熟悉中级概念。"
    }

    # 获取对应级别的解释方式，若未提供则默认为'初学者'
    level_string = explanation_levels.get(level_of_explanation, explanation_levels['初学者'])

    # 确定创意和幽默的描述
    creativity_string = (
        "" if creativity_level < 4
        else "在解释时富有创意，以便于理解。" if creativity_level < 7
        else "在解释时富有创意并使用类比。"
    )

    humour_string = (
        "" if humour_level < 4
        else "在解释时带一点幽默。" if humour_level < 7
        else "在解释时增添笑话，使学习更有趣。"
    )

    # 构造提示词，综合所有参数生成课程内容的描述
    prompt = (
        f"请生成一个关于{topic_name}的课程内容。"
        f"授课对象为：{age_str}岁的学生。"
        f"解释关键概念。"
        f"课程内容要求：{level_string}{creativity_string}{humour_string}。"
        f"输出应为Markdown格式。"
        f"只生成 # 和 ## 两层目录结构，其他都作为要点内容"
        f"除了课程内容本身，不要输出其他内容"
    )

    # 直接调用 API 获取课程脚本
    completion = client.chat.completions.create(
        model="qwen-max",
        messages=[
            {"role": "system", "content": "你是一名专注于科学普及的课程讲师，负责为学生提供清晰的课程内容"},
            {"role": "user", "content": prompt},
        ],
        stream=True
    )

    # 解析 API 返回结果，提取生成的课程脚本内容
    generated_content = ""
    for chunk in completion:
        chunk_content = chunk.choices[0].delta.content
        generated_content += chunk_content
        print(chunk_content, end="")

    # 返回生成的课程脚本内容
    return generated_content

# 读取配置文件中的插图提示词文件路径
illustrations_prompt_file_path = project_config["illustrations_prompt_file_path"].format(title=project_config["title"])

# 读取配置文件中的课程内容信息
title = project_config["title"]
level_of_explanation = project_config["level_of_explanation"]
age = project_config["age"]
creativity_level = project_config["creativity_level"]
humour_level = project_config["humour_level"]

# 调用函数生成课程脚本
script = create_course_script(title, level_of_explanation, age, creativity_level, humour_level)

# 调用函数生成插画提示词
illustrations_prompt = create_illustration_prompt(script)

# 调用函数保存插画提示词
save_file(illustrations_prompt, illustrations_prompt_file_path)